package com.hyc.serviceCenter;

import cn.hutool.core.collection.ConcurrentHashSet;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.hyc.cache.ServiceCache;
import com.hyc.constant.NacosConstant;
import com.hyc.serviceCenter.loadbalance.impl.ConsistencyHashBalance;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * @author 冷环渊
 * @date 2025/6/10 14:30
 * @description NacosServiceCenter
 */
public class NacosServiceCenter {
    private NamingService namingService;
    private ServiceChangeListener serviceChangeListener;
    private ConcurrentHashSet<String> subscribeServiceSet;

    private ServiceCache serviceCache;
    private boolean checkRetry = false;
    //命名空间
    private String nameScope;

    public NacosServiceCenter() {
        this.serviceCache = new ServiceCache();
        init();
    }

    public void init() {
        try {
            Properties properties = new Properties();
            properties.setProperty("username", NacosConstant.NACOS_USERNAME);
            properties.setProperty("password", NacosConstant.NACOS_PASSWORD);
            properties.setProperty("serverAddr", NacosConstant.SERVER_ADDR);
            if (nameScope != null) {
                properties.setProperty("namespace", nameScope);
            }
            namingService = NamingFactory.createNamingService(properties);
            serviceChangeListener = new ServiceChangeListener(serviceCache);
            subscribeServiceSet = new ConcurrentHashSet<>();
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }


    public InetSocketAddress serviceDiscovery(String serviceName) {
        try {
            List<Instance> instances = namingService.selectInstances(serviceName, NacosConstant.RPC_GROUP_NAME, true);
            if (!subscribeServiceSet.contains(serviceName)) {
                namingService.subscribe(serviceName, NacosConstant.RPC_GROUP_NAME, serviceChangeListener);
            }
            //使用缓存
            List<String> addressList = serviceCache.getCacheList(serviceName);
            if (addressList.isEmpty()) {
                addressList = instances.stream()
                        .map(Instance::toInetAddr)
                        .collect(Collectors.toList());
            }
            String s = instances.get(0).getMetadata().get(serviceName);
            checkRetry = Boolean.parseBoolean(s);
            String balanceAddress = new ConsistencyHashBalance().balance(addressList);
            return parseAddress(balanceAddress);
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
    }

    public boolean checkRetry() {
        return checkRetry;
    }

    public InetSocketAddress parseAddress(String address) {
        String[] split = address.split(":");
        return new InetSocketAddress(split[0], Integer.parseInt(split[1]));
    }

}
